#pragma once

#include <vector>
#include <string>
#include <memory>
#include <functional>
#include <unistd.h>
#include <pthread.h>
#include "Task.hpp"
#include "Thread.hpp"
#include "BlockingQueue.hpp" // CP模型

namespace ccc
{
#define THREAD_NUM 10

    template<class T>
    class ThreadPool
    {
        using func_t = std::function<void(T&)>; // 包装器

    public:
        ThreadPool(func_t func, int num = THREAD_NUM)
            :_num(num), _func(func)
        {
        }

        ~ThreadPool()
        {
            // 等待线程退出
            for(auto &t : _threads)
                t.join();
        }

        void init()
        {
            // 创建一批线程
            for(int i = 0; i < _num; i++)
                _threads.push_back(Thread(i, threadRoutine, this));
        }

        void start()
        {
            // 启动线程
            for(auto &t : _threads)
                t.run();
        }

        // 提供给线程的回调函数（已修改返回类型为 void）
        static void threadRoutine(void *args)
        {
            // 避免等待线程，直接剥离
            pthread_detach(pthread_self());

            auto ptr = static_cast<ThreadPool<T>*>(args);

            while (true)
            {
                // 从CP模型中获取任务
                T task = ptr->popTask();


                task();
                ptr->callBack(task); // 回调函数
            }
        }

        // 装载任务
        void pushTask(const T& task)
        {
            _blockqueue.Push(task);
        }
    
    protected:
        func_t callBack(T &task)
        {
            _func(task);
        }

        T popTask()
        {
            T task;
            _blockqueue.Pop(&task);

            return task;
        }

    private:
        std::vector<Thread> _threads;
        int _num; // 线程数量
        BlockQueue<T> _blockqueue; // 阻塞队列
        func_t _func;
    };
}
